package study.javaee.practice.controller;

import cn.hutool.crypto.symmetric.SymmetricCrypto;
import io.swagger.annotations.ApiOperation;
import org.hibernate.validator.constraints.CodePointLength;
import org.hibernate.validator.constraints.Length;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import study.javaee.practice.common.api.CommonResult;
import study.javaee.practice.entity.User;
import study.javaee.practice.property.SecurityProperty;
import study.javaee.practice.service.AsymEncService;
import study.javaee.practice.service.AuthService;
import study.javaee.practice.service.SymEncService;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Validated
@RequestMapping("/auth")
@RestController
public class AuthController {

    @Autowired
    AsymEncService asymEncService;
    @Autowired
    SymEncService symEncService;
    @Autowired
    SecurityProperty securityProperty;
    @Autowired
    AuthService authService;

    @ApiOperation("获取加密公钥")
    @GetMapping("/pub_key")
    public CommonResult<Map<String, Object>> getPubKey(){
        CommonResult<Map<String, Object>> data = CommonResult.success(new HashMap<>(1), "成功");
        data.getData().put("pub_key", asymEncService.getStrPubKey());
        return data;
    }

    @ApiOperation(value = "设置对称加密密钥",notes = "需要将数据")
    @PostMapping("/sym_key")
    public CommonResult<Object> setSymKey(@NotEmpty @CodePointLength(min = 16, max = 16) String sym_key,
                                          @RequestParam(defaultValue = "") @Length(min = 16, max = 16) String iv,
                                          HttpServletRequest request){
        SymmetricCrypto crypto = symEncService.setCrypto(sym_key, iv, request);
        Map<String, Object> data = new HashMap<>(1);
        data.put("test_data", symEncService.encryptToStr("密钥配对成功", crypto));
        return CommonResult.success(data, "对称密钥设置成功");
    }

    @ApiOperation("获取图片验证码,暂不使用")
    @GetMapping("/ver_code")
    public CommonResult<Object> verCode(HttpServletRequest request,
                                        @NotEmpty @Pattern(regexp = "login") String usage){
        Map<String, Object> data = new HashMap<>(1);
        if (Objects.equals(usage, "login")){
            data.put("code_img", authService.requestImgLoginVerCode(request));
        }
        return CommonResult.success(data);
    }

    /**
     *
     * @param email 邮箱
     * @param usage 用途， 例如 login, register
     */
    @ApiOperation("获取邮箱验证码")
    @GetMapping("/email_code")
    public CommonResult<Object> emailCode(@NotEmpty @Email String email,
                                          @NotEmpty @Pattern(regexp = "(?:login)|(?:register)") String usage){
        if (Objects.equals(usage, "login")){
            authService.requestLoginEmailVerCode(email);
        }else if (Objects.equals(usage, "register")){
            authService.requestRegisterEmailVerCode(email);
        }
        return CommonResult.success(null);
    }

    @ApiOperation("登录")
    @PostMapping("/login")
    public CommonResult<Object> login(@Email @NotEmpty String email,
                                      @NotEmpty @Length(min = 6, max = 20, message = "密码长度在6到20之间") String password,
                                      @RequestParam("ver_code") @NotEmpty @Length(min = 4,max = 4) String verCode,
                                      @RequestParam(defaultValue = "false") Boolean rememberMe,
                                      HttpServletRequest request
    ){
        User user = authService.logIn(email, password, verCode,request ,rememberMe);
        Map<String, Object> data = new HashMap<>(1);
        user.setPassword(null);
        data.put("user",user);
        return CommonResult.success(data, "登录成功");
    }

    @ApiOperation("注册")
    @PostMapping("/register")
    public CommonResult<Object> register(@Validated User user, @NotEmpty @Length(min = 6, max = 6) String ver_code){
        authService.register(user, ver_code);
        return CommonResult.success("注册成功");
    }

    @ApiOperation("注销登录")
    @PostMapping("/logout")
    public CommonResult<Object> logout(HttpServletRequest request){
        authService.logout(request);
        return CommonResult.success(null);
    }

    @ApiOperation("找回密码")
    @PostMapping("/findPwd")
    public CommonResult<Objects> findPassword(
            @NotEmpty @Email String email,
            @NotEmpty @Length(min = 6, max = 20, message = "密码长度在6到20之间") String password,
            @NotEmpty @RequestParam("ver_code") @Length(min = 6,max = 6) String verCode){
        authService.findUserPassword(email , password, verCode);
        return CommonResult.success(null);
    }
}
